#include"orb.h"
#include"omp.h"
orb_matcher::orb_matcher(const std::string& filename= "BruteForce-Hamming")
{
    detector = ORB::create();
    descriptor = ORB::create();
    // Ptr<FeatureDetector> detector = FeatureDetector::create(detector_name);
    // Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create(descriptor_name);
    matcher = DescriptorMatcher::create(filename);
}
int orb_matcher::update_mats(Mat a, Mat b) {
    return true;
}
int orb_matcher::match(frame* Frame, double min_dist, double max_dist,Mutex *frame_lock)
{
    Mat img_1 = Frame->old_pic;
    Mat img_2 = Frame->common_pic;
    detector->detect(img_1, keypoints_1);
    detector->detect(img_2, keypoints_2);
    if (keypoints_2.size() < 5)
        return 0;
    //cout << keypoints_1.size();
    //-- �ڶ���:���ݽǵ�λ�ü��� BRIEF ������
    this->descriptor->compute(img_1, keypoints_1, descriptors_1);
    this->descriptor->compute(img_2, keypoints_2, descriptors_2);


    static Mat outimg1;
    //drawKeypoints(img_1, keypoints_1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
    //imshow("ORB������", outimg1);
    vector<DMatch> matches;
    //BFMatcher matcher ( NORM_HAMMING );
    matcher->match(descriptors_1, descriptors_2, matches);

    //-- ���Ĳ�:ƥ����ɸѡ
#pragma omp parallel for num_threads(4) schedule(dynamic)
    for (int i = 0; i < descriptors_1.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }

    // printf("-- Max dist : %f \n", max_dist);
    // printf("-- Min dist : %f \n", min_dist);

     //��������֮��ľ��������������С����ʱ,����Ϊƥ������.����ʱ����С�����ǳ�С,����һ������ֵ30��Ϊ����.
    std::vector< DMatch > good_matches;
//#pragma omp parallel for num_threads(4) schedule(dynamic)
    for (int i = 0; i < descriptors_1.rows; i++)
    {
        if (matches[i].distance <= max(2 * min_dist, 30.0))
        {
            good_matches.push_back(matches[i]);
        }
    }

    //-- ���岽:����ƥ����
    //drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_match);
    //drawMatches(img_1, keypoints_1, img_2, keypoints_2, good_matches, img_goodmatch);
    //imshow("����ƥ����", img_match);
    //imshow("�Ż���ƥ����", img_goodmatch);
    //img_1 = img_2.clone();
    frame_lock->lock();
    Frame->key_points1 = keypoints_1;
    Frame->key_points2 = keypoints_2;
    Frame->matches = matches;
    Frame->good_matches = good_matches;
    frame_lock->unlock();
    //waitKey(1);
    return  1;
}
match_return orb_matcher::match(Mat img_1,Mat img_2,Mat forbiden_Zone,double min_dist=10000,double max_dist=0){
    detector->detect(img_1, keypoints_1);
    detector->detect(img_2, keypoints_2);
    if (keypoints_2.size() < 5)
        return old_result;
    //cout << keypoints_1.size();
    //-- �ڶ���:���ݽǵ�λ�ü��� BRIEF ������
    this->descriptor->compute(img_1, keypoints_1, descriptors_1);
    this->descriptor->compute(img_2, keypoints_2, descriptors_2);


    static Mat outimg1;
    drawKeypoints(img_1, keypoints_1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
    //imshow("ORB������", outimg1);
    vector<DMatch> matches;
    //BFMatcher matcher ( NORM_HAMMING );
    matcher->match(descriptors_1, descriptors_2, matches);

    //-- ���Ĳ�:ƥ����ɸѡ

    for (int i = 0; i < descriptors_1.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }

    // printf("-- Max dist : %f \n", max_dist);
    // printf("-- Min dist : %f \n", min_dist);

     //��������֮��ľ��������������С����ʱ,����Ϊƥ������.����ʱ����С�����ǳ�С,����һ������ֵ30��Ϊ����.
    std::vector< DMatch > good_matches;

    for (int i = 0; i < descriptors_1.rows; i++)
    {
        if (matches[i].distance <= max(2 * min_dist, 30.0))
        {
            good_matches.push_back(matches[i]);
        }
    }

    //-- ���岽:����ƥ����
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, good_matches, img_match);
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, good_matches, img_goodmatch);
    //imshow("����ƥ����", img_match);
    //imshow("�Ż���ƥ����", img_goodmatch);
    //img_1 = img_2.clone();
    std::get<2>(result) = keypoints_1;
    std::get<3>(result) = keypoints_2;
    std::get<1>(result) = matches;
    std::get<0>(result) = good_matches;
    std::get<2>(old_result) = keypoints_1;
    std::get<3>(old_result) = keypoints_2;
    std::get<1>(old_result) = good_matches;
    std::get<0>(old_result) = good_matches;
    return result;

    
}



